﻿using Expect.Core.Errors;
using Microsoft.VisualStudio.TestTools.UnitTesting;
//using MakeSure = NUnit.Framework.Assert;
//using NUnit.Framework.SyntaxHelpers;

namespace Expect.Core.Test
{
    using Expect.Core.BaseClasses;

    /// <summary>
    /// Summary description for FlowTest
    /// </summary>
    [TestClass]
//    [SpecificationContainer]
    public class FlowTest
    {
        [TestMethod]
        public void FlowTest_execute_inline()
        {
            SpecificationDefinition test = new SpecificationDefinition();
            test.ClassName = "FlowTestImplementation";

            test.AddFixture()
                .WithRow("ActorFixtureImpl")
                .WithRow("press", "My press test")
                .WithRow("enter", "My enter test", string.Empty, "6")
                .WithRow("reject", "My check test", string.Empty, "12")
                .WithRow("check", "My check test", string.Empty, "6");

            test.AddFixture()
                .WithRow("Verify that user", "John", "is", "connected");

            test.AddFixture()
                .WithRow("user", "John", "create", "mychat", "room")
                .WithRow("user", "John", "enter", "mychat", "room");

            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(this, test);
            if (!test.IsSuccessful)
            {
                Assert.Fail(test.GetMessageForFailedResult());
            }

        }

        [TestMethod]
        public void FlowTest_execute_inline_WithContextPreset()
        {
            SpecificationDefinition test = new SpecificationDefinition();
            test.ClassName = "FlowTestImplementation";
            test.Context = new DefaultExecutionContext();
            test.Context.Container = this;
            
            var fixture = test.AddFixture();
            fixture.WithRow("ActorFixtureImpl");
            fixture.WithRow("press", "My press test");
            fixture.WithRow("enter", "My enter test", string.Empty, "6");
            fixture.WithRow("reject", "My check test", string.Empty, "12");
            fixture.WithRow("check", "My check test", string.Empty, "6");

            test.AddFixture()
                .WithRow("Verify that user", "John", "is", "connected");

            test.AddFixture()
                .WithRow("user", "John", "create", "mychat", "room")
                .WithRow("user", "John", "enter", "mychat", "room");

            test.CalculateResult();

            if (!test.IsSuccessful)
            {
                Assert.Fail(test.GetMessageForFailedResult());
            }
        }

        [TestMethod]
        //[ExpectedException(typeof(UnresolvedMethodError))]
        public void FlowTest_method_not_found()
        {
            SpecificationDefinition test = new SpecificationDefinition();

            test.AddFixture()
                .WithRow("FlowTestImplementation");

            test.AddFixture()
                .WithRow("ActorFixtureImpl")
                .WithRow("press", "My press test")
                .WithRow("enter", "My enter test", string.Empty, "6")
                .WithRow("reject", "My check test", string.Empty, "12")
                .WithRow("check", "My check test", string.Empty, "6");

            //Method IsStill does not exits...
            test.AddFixture()
                .WithRow("Verify that user", "John", "is still", "connected");

            test.AddFixture()
                .WithRow("user", "John", "create", "mychat", "room")
                .WithRow("user", "John", "enter", "mychat", "room");

            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(this, test);
            Assert.IsFalse(test.IsSuccessful);
            Assert.IsTrue(test.HasError<ElementNotFoundError>());
            Assert.IsTrue(test.HasError<ElementNotFoundError>(e => e.Kind == ElementKind.Method));
        }

        [TestMethod]
        //[ExpectedException(typeof(UnresolvedMethodError))]
        public void FlowTest_fluent_method_not_found()
        {
            SpecificationDefinition test = new SpecificationDefinition();

            test.AddFixture()
                .WithRow("FlowTestImplementation");

            test.AddFixture()
                .WithRow("ActorFixtureImpl")
                .WithRow("press", "My press test")
                .WithRow("enter", "My enter test", string.Empty, "6")
                .WithRow("reject", "My check test", string.Empty, "12")
                .WithRow("check", "My check test", string.Empty, "6");

            test.AddFixture()
                .WithRow("Verify that user", "John", "is", "connected");

            test.AddFixture()
                .WithRow("user", "John", "create", "mychat", "room")
                .WithRow("user", "John", "enter", "mychat", "room")
                .WithRow("user", "John", "exit", "mychat", "room");

            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(this, test);
            Assert.IsFalse(test.IsSuccessful);
            Assert.IsTrue(test.HasError<ElementNotFoundError>(e => e.Kind == ElementKind.Method));
        }
    }
}
